package com.abctime.demo.eval_engine;


import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;

import com.abctime.api.VoiceEvalEngine;
import com.constraint.CoreProvideTypeEnum;
import com.xs.BaseSingEngine;
import com.xs.SingEngine;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;

/**
 * description: ssound包对应的-语音工具引擎，只支持线上语音评测方式
 * author: KisenHuang
 * email: KisenHuang@163.com
 * time: 2018/9/28 下午1:06
 */

public class ABCVoiceEvalEngineNet implements VoiceEvalEngine {

    private String appId = "t123";
    private String appKey = "8ebb9ddf76fa4b11bde4671387b39897";
    private SingEngine engine;
    private BaseSingEngine.ResultListener mResultListener;
    private String voiceEvalPath;
    private boolean running;
    private OnVoiceEvalResultListener mOnVoiceEvalResultListener;
    private OnRecordListener mOnRecordListener;
    private Handler mHandler;
    private Runnable mDelayRunnable;

    @Override
    public void newEngine(Context context) {
        mHandler = new Handler(Looper.getMainLooper());
        createRecPath(context.getApplicationContext());
        engine = SingEngine.newInstance(context);
        running = false;

        try {
            JSONObject cfg_init = this.engine.buildInitJson(appId, appKey);
            this.engine.setNewCfg(cfg_init);
        } catch (Exception var8) {
            var8.printStackTrace();
        }
//        engine.setOpenVad(false, "vad.0.1.bin");
        engine.setServerType(CoreProvideTypeEnum.CLOUD);
        engine.setFrontVadTime(2000);
        engine.setBackVadTime(2000);
        createResultListener();
        engine.setListener(mResultListener);
        try {
            engine.newEngine();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        mDelayRunnable = new Runnable() {
            @Override
            public void run() {
                //超时结束
                if (mOnRecordListener != null)
                    mOnRecordListener.onRecordStop(new Throwable(""));
                cancelRecord();
            }
        };
    }

    private void createRecPath(Context context) {
        if (context != null) {
            File externalFilesDir = context.getExternalFilesDir(Environment.DIRECTORY_DCIM);
            if (externalFilesDir != null) {
                voiceEvalPath = externalFilesDir.getAbsolutePath();
            }
        }
    }

    private void createResultListener() {
        mResultListener = new BaseSingEngine.ResultListener() {

            @Override
            public void onBegin() {
            }

            @Override
            public void onResult(JSONObject object) {
                running = false;
                if (mOnVoiceEvalResultListener != null) {
                    JSONObject resultStr = object.optJSONObject("result");
                    String overall = resultStr.optString("overall");
                    String recordId = object.optString("tokenId");
                    //录音时间 小于1秒 ，不触发监听
                    int systime = resultStr.optInt("systime", 1000);
                    try {
                        if (Integer.valueOf(overall) <= 0 && systime < 1000) {
                            cancelRecord();
                            return;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    if (systime < 1000)
                        return;

                    final String wavFilePath = voiceEvalPath + "/" + recordId + ".wav";
                    //分数最小为 1分
                    if (Integer.valueOf(overall) <= 0) {
                        overall = "1";
                    }
                    mOnVoiceEvalResultListener.onVoiceEvalResult(wavFilePath, overall);
                }
            }

            @Override
            public void onEnd(int i, String s) {
                running = false;
                if (i != 0 && mOnRecordListener != null) {
                    mOnRecordListener.onRecordStop(new Throwable(s));
                }
                if (mHandler != null) {
                    mHandler.removeCallbacks(mDelayRunnable);
                }
            }

            @Override
            public void onUpdateVolume(int i) {
            }

            @Override
            public void onFrontVadTimeOut() {
                running = false;
            }

            @Override
            public void onBackVadTimeOut() {
                running = false;
            }

            @Override
            public void onRecordingBuffer(byte[] bytes, int i) {
            }

            @Override
            public void onRecordLengthOut() {
            }

            @Override
            public void onReady() {
            }

            @Override
            public void onPlayCompeleted() {
            }

            @Override
            public void onRecordStop() {
                running = false;
                if (mOnRecordListener != null)
                    mOnRecordListener.onRecordStop(null);
            }
        }

        ;
    }

    @Override
    public void setOnVoiceEvalStopListener(OnVoiceEvalResultListener listener) {
        mOnVoiceEvalResultListener = listener;
    }

    @Override
    public void setOnRecordStopListener(OnRecordListener listener) {
        mOnRecordListener = listener;
    }

    @Override
    public boolean isAvailable() {
        return engine != null;
    }

    @Override
    public boolean isRecording() {
        return running;
    }

    @Override
    public void startRecordEval(String text) {
        if (this.engine != null) {
            try {
                JSONObject request = new JSONObject();
                request.put("coreType", "en.word.score");
                request.put("refText", text);
                request.put("rank", 100);

                this.engine.setWavPath(voiceEvalPath);
                JSONObject startCfg = this.engine.buildStartJson("guest", request);
                this.engine.setStartCfg(startCfg);
                this.engine.start();
                running = true;
            } catch (Exception var5) {
                var5.printStackTrace();
            }
        }
    }

    @Override
    public void stopRecord() {
        if (engine != null) {
            engine.stop();
            //录音结束，启动评测计时
            mHandler.postDelayed(mDelayRunnable, 5000);
            running = false;
        }
    }

    @Override
    public void cancelRecord() {
        if (engine != null)
            engine.cancel();
    }

    @Override
    public void deleteRecord() {
        if (engine != null) {
            engine.deleteSafe();
            engine = null;
        }
        mOnVoiceEvalResultListener = null;
        mOnRecordListener = null;
        mResultListener = null;
        voiceEvalPath = null;
        if (mHandler != null) {
            mHandler.removeCallbacks(mDelayRunnable);
            mDelayRunnable = null;
            mHandler = null;
        }
    }

    @Override
    public boolean isNetworking() {
        return true;
    }

    @Override
    public int leastRecordMillisecond() {
        return 1000;
    }
}
